// 开发环境自定义插件

import {loadEnv, type Plugin} from 'vite'
import type {AddressInfo} from 'net'
// 导入子进程，用来启动electron和传递服务url
import { ChildProcess, spawn } from 'child_process'
// 导入electron命令
import electron from 'electron'
//导入文件操作相关对象
import fs from 'fs'
import path from 'path'
// 引入esbuild, 将electron的主进程ts打包成js, electron 不能识别ts
import {BuildResult, buildSync} from 'esbuild'

// 递归拷贝文件夹及其内容  
function copyDirSync(src: string, dest: string) {
    // 确保目标目录存在  
    if (!fs.existsSync(dest)) {
        fs.mkdirSync(dest, { recursive: true });
    }

    fs.readdirSync(src).forEach(file => {
        const srcFile = path.join(src, file);
        const destFile = path.join(dest, file);

        // 递归拷贝子目录  
        if (fs.lstatSync(srcFile).isDirectory()) {
            copyDirSync(srcFile, destFile);
        } else {
            // 拷贝文件  
            fs.copyFileSync(srcFile, destFile);
        }
    });
}


// 打包electron.ts
const electronBuild2Js = () => {
    // 每次打包前先删除编译后目录，再进行编译
    let targetExistFlag = fs.existsSync('electronbuild')
    if(targetExistFlag){
        console.log('electronbuild 目录存在，执行删除')
        fs.rmSync('electronbuild',{recursive:true})
    }else{
        console.log('electronbuild 目录不存在，无需删除')
    }

    // 编译打包electron 入口ts文件
    let buildRes: BuildResult = buildSync({
        entryPoints: ['electron/**/*.ts'],
        bundle: true,
        outdir: 'electronbuild',
        platform: 'node',
        target: 'node20',
        external: ['electron']
    })
    console.log('编译 electron ts 文件结果:',buildRes)

    // 拷贝electron编译后文件按到build目录
    const sourceDir = path.join(__dirname, '../electronbuild');
    const destinationDir = path.join(__dirname, '../build');

    copyDirSync(sourceDir, destinationDir);
    console.log('electronbuild文件夹及其内容拷贝完成！');
}

// 自定义插件
export const ElectronDevPlugin = (): Plugin => {
    return {
        name: 'electron-dev-plugin',
        configureServer(server) {
            // 编译electronmain.ts
            electronBuild2Js()

            server.httpServer?.on('listening', () => {
                //1. 获取vue3服务地址
                let addressInfo = server.httpServer?.address() as AddressInfo
                const devUrl = `http://localhost:${addressInfo.port}`
                // 2. 加载开发环境的环境变量
                let envParams = loadEnv('development',path.resolve(process.cwd(),'./environmentconfig'));
                console.log('plugins-dev : 获取的环境变量 ： ',envParams.VITE_ENV)
                // 3. 启动electron, url通过进程传参到electron中
                let electronProcess = spawn(electron + '', ['build/electronMain.js', devUrl], {stdio: 'inherit'}) as ChildProcess
                console.log('plugins-dev : electronProcess : ', electronProcess.pid)

                // 监测electron下文件是否发生变化， electron热启动
                fs.watch('electron', () => {
                    console.log('plugins-dev : electron 目录中的文件发生改变了')
                    electronProcess.kill()
                    // electron执行一下编译,然后在重新执行
                    electronBuild2Js();
                    electronProcess = spawn(electron+'',['build/electronMain.js',devUrl],{ stdio: 'inherit' }) as ChildProcess
                })
            })
        }
    }
}